package com.zhangyj.impl.component.grid;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;

import com.zhangyj.component.grid.HTMLTable;
import com.zhangyj.component.grid.model.ITableModel;
import com.zhangyj.component.grid.render.ICellRender;
import com.zhangyj.impl.component.grid.render.DefaultIntegerCellRender;
import com.zhangyj.impl.component.grid.render.DefaultStringCellRender;

public class DefaultHTMLTable extends HTMLTable {

	ITableModel model = null;
	Map<Class<?>, ICellRender> renderers = new HashMap<Class<?>, ICellRender>();

	public DefaultHTMLTable(ITableModel model) {
		this.model = model;
		this.setDefaultRenderer(Integer.class, new DefaultIntegerCellRender());
		this.setDefaultRenderer(String.class, new DefaultStringCellRender());
	}

	public DefaultHTMLTable(final Object[][] arr) {
		this(new ITableModel() {
			private Object[] item = null;
			private int index = -1;

			public boolean next() {
				index++;
				if (index < arr.length) {
					this.item = arr[index];
					return true;
				}
				return false;
				// TODO Auto-generated method stub

			}

			public Class<?> getColumnClass(int columnIndex) {
				if (arr[0][columnIndex] == null) {
					return String.class;
				}
				return arr[0][columnIndex].getClass();
			}

			public int getColumnCount() {
				return arr[0].length;
			}

			public String getColumnName(int columnIndex) {
				return null;
			}

			public int getColumnWidth(int columnIndex) {
				return 30;
			}

			public Object getValueAt(int columnIndex) {
				return this.item[columnIndex];
			}

		});
	}

	public void getHtmlHeadCode(Writer buffer) throws IOException {
		int columnCount = this.model.getColumnCount();
		buffer.append("<thead><tr>");
		for (int j = 0; j < columnCount; j++) {
			int width = this.model.getColumnWidth(j);
			if (width == 0) {
				buffer.append("<th width=\"100\">");
			} else {
				buffer.append("<th width=\"" + this.model.getColumnWidth(j) + "\">");
			}
			buffer.append(this.model.getColumnName(j));
			buffer.append("</th>");
		}
		buffer.append("</tr>");
		buffer.append("</thead>");
	}

	public void getHtmlBodyCode(Writer buffer) throws IOException {
		int columnCount = this.model.getColumnCount();
		buffer.append("<tbody>");
		while (this.model.next()) {
			buffer.append("<tr>");
			for (int j = 0; j < columnCount; j++) {
				ICellRender render = this.renderers.get(this.model.getColumnClass(j));
				if (render == null)
					render = this.renderers.get(String.class);
				render.writer(this, buffer, this.model.getValueAt(j), false, false, j);
			}
			buffer.append("</tr>");
		}
		buffer.append("</tbody>");
	}

	public void setDefaultRenderer(Class<?> className, ICellRender render) {
		this.renderers.put(className, render);
	}

	public void println(Writer wirter) throws IOException {
		wirter.append("<table class=\"grid\">");
		getHtmlHeadCode(wirter);
		getHtmlBodyCode(wirter);
		wirter.append("</table>");
	}

	public static void main(String[] args) {
		try {
			HTMLTable table = new DefaultHTMLTable(new Object[][] { { 1, "bbb " }, { 2, "ddd" } });
			Writer writer = new OutputStreamWriter(System.out);
			table.println(writer);
			writer.flush();
			writer.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}
